package cn.monkey.chat.server.connect.chat.protocol.http.ws;

import cn.monkey.chat.server.connect.chat.netty.NettyChatExchangeManager;
import cn.monkey.chat.server.data.account.UserSession;
import cn.monkey.chat.server.proto.Command;
import cn.monkey.chat.server.proto.Package;
import cn.monkey.chat.server.proto.json.JsonMessage;
import cn.monkey.chat.server.proto.json.JsonPackage;
import cn.monkey.chat.server.proto.json.JsonUser;
import com.google.gson.Gson;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class TextChatMessageInboundHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    protected final NettyChatExchangeManager nettyChatExchangeManager;
    protected final Gson gson = new Gson();

    private static final Logger log = LoggerFactory.getLogger(TextChatMessageInboundHandler.class);

    public TextChatMessageInboundHandler(NettyChatExchangeManager nettyChatExchangeManager) {
        this.nettyChatExchangeManager = nettyChatExchangeManager;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
            nettyChatExchangeManager.findOrCreate(this.key(ctx), ctx.channel());
            this.fireOnlineEvent(ctx);
        }
        super.userEventTriggered(ctx, evt);
    }

    void fireOnlineEvent(ChannelHandlerContext ctx) {
        Attribute<UserSession> attribute = ctx.channel().attr(AttributeKey.valueOf(UserSession.KEY));
        UserSession userSession = attribute.get();
        if (userSession == null) {
            log.error("can not find userSession");
            throw new IllegalArgumentException("can not find userSession");
        }
        List<String> friends = userSession.getFriends();
        List<String> groups = userSession.getGroups();
        if (groups != null) {
            for (String groupId : groups) {
                JsonPackage jsonPackage = new JsonPackage();
                jsonPackage.setGroupId(groupId);
                jsonPackage.setCmdType(Command.ONLINE);
                ctx.fireChannelRead(jsonPackage);
            }
        }
        if (friends != null) {
            for (String friendId : friends) {
                JsonPackage jsonPackage = new JsonPackage();
                JsonUser jsonUser = new JsonUser();
                jsonUser.setUid(friendId);
                JsonMessage jsonMessage = new JsonMessage();
                jsonMessage.setTo(List.of(jsonUser));
                jsonPackage.setData(jsonMessage);
                jsonPackage.setCmdType(Command.ONLINE);
                ctx.fireChannelRead(jsonPackage);
            }
        }
    }

    private String key(ChannelHandlerContext ctx) {
        Attribute<UserSession> attribute = ctx.channel().attr(AttributeKey.valueOf(UserSession.KEY));
        UserSession userSession = attribute.get();
        if (userSession == null) {
            log.error("can not find userSession");
            ctx.close();
            throw new IllegalArgumentException("empty userSession");
        }
        return userSession.getUserId();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        ctx.fireChannelRead(gson.fromJson(msg.text(), JsonPackage.class));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO
        super.channelInactive(ctx);
    }
}
